//https://apple.stackexchange.com/questions/28928/what-is-the-osx-equivalent-to-windows-appdata-folder
//https://stackoverflow.com/questions/21366350/program-data-folders-in-linux

#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "curlEasy.h"

#define UPDATE_SECONDS_DATA 2
#define UPDATE_SECONDS_GUI 1

/*============================================================================*/

void syncProgressBars();
void switchToStatusScreen();
void switchToFileManager();
void syncFileList();
void supportStartMainGUI();
void supportStartCodeInput();

/*============================================================================*/

// From main.c
extern CURL* _generalUseCurl; // Only use from main thread please
extern char* _userAccessToken;

extern int totalStatuses;
extern singleStatus* myStatuses;

extern int totalFileInfos;
extern fileInfo* currentFileInfo;

extern int totalHDDL;
extern downloadInstance** currentHDDL;

extern int totalFileInfos;
extern fileInfo* myFileInfos;
extern fileInfo currentFolderParent;
extern char* currentBrowserDir;

extern char* homeDir;
extern char* configDir;
extern char* downloadsDir;

/*============================================================================*/
// What our quick GUI function update calls should be updating
#define SIGNAL_NONE 0
#define SIGNAL_UPDATEBARS 1
#define SIGNAL_UPDATEFILELIST 2
#define SIGNAL_UDPATEHDDLPROGRESS 3

// What our internet updating thread should be doing
#define SIGNAL_DLNONE 0
#define SIGNAL_DLBARS 1
#define SIGNAL_DLFILELIST 2

#define ARRAYINDEXKEY "legguyarrayindex"

#define ENABLETASKBAR 0
/*============================================================================*/

struct deletionInfo{
	int* totalDeletions;
	int passedIndex;
};

/*============================================================================*/

GtkWidget* mainWindow;
// Screens
GtkWidget* mainBox=NULL;
GtkWidget* statusUIBox=NULL;
GtkWidget* fileManagerUIBox=NULL;
GtkWidget* localDLListUIBox=NULL;
// Variables for torrent status screen
GtkWidget* progressBox=NULL;
GtkWidget** progressBars=NULL; // This is an array
int totalProgressBars=0;
// Variables for file browser
GtkWidget* fileListBox=NULL;
int totalGUIFileList=0;
GtkWidget** guiFileListEntry=NULL;
GtkWidget* folderViewerTopLabel=NULL;
//
GtkWidget* tempStuffBox=NULL;

// Variables for download manager
GtkWidget** guiHDDLBars=NULL;
int numHDDLBars=0;

// The ID returned from g_timeout_add_seconds call for the function that's called to update GUI
guint guiRefreshFunctionID; // g_source_remove to stop
guint dataRefreshFunctionID;
int updateGUISignal = SIGNAL_NONE;
int updateDataSignal = SIGNAL_DLNONE;
char isOneshotData=0;
char isOneshotGUI=0;

volatile signed char dataThreadRunning=0;

pthread_t dataThread=0;

GdkRGBA _folderColor;

char* currentFolderBrowseCode=NULL;

/*============================================================================*/

/*void _listCoutnerForeachHelper(GtkListBox* box, GtkListBoxRow* row, gpointer user_data){
	printf("what?\n");
	++*((int*)user_data);
}
int getListBoxRows(GtkWidget* _passedListbox){
	int _foundTotalRows=0;
	gtk_list_box_selected_foreach(GTK_LIST_BOX(_passedListbox),_listCoutnerForeachHelper,&_foundTotalRows);
	return _foundTotalRows;
}*/

gboolean gtkHideInsteadOfClose(GtkWidget *widget, GdkEvent *event, gpointer data){
	#if ENABLETASKBAR
		gtk_widget_hide(widget);
		return 1;
	#else
		return 0;
	#endif
}

void clearFileList(){
	gtk_label_set_text(GTK_LABEL(folderViewerTopLabel),"Please wait...");
	int i;
	for (i=0;i<totalGUIFileList;++i){
		gtk_widget_destroy(guiFileListEntry[i]);
	}
	totalGUIFileList=0;
}

void* threadedDownloadFilelist(void* _passedData){
	CURL* _personalCurl = newCurl();
	
	char* _passCode;
	if (currentFolderBrowseCode!=NULL){
		_passCode = strdup(currentFolderBrowseCode);
	}else{
		_passCode=NULL;
	}

	updateFileInfo(_personalCurl,_passCode);
	updateGUISignal = SIGNAL_UPDATEFILELIST;
	
	free(_passCode);

	deleteCurl(_personalCurl);
	dataThreadRunning=0;
	if (_passedData==NULL){
		pthread_exit(NULL);
	}
	return NULL;
}


void* threadedDownloadBars(void* _passedData){
	CURL* _personalCurl = newCurl();
	
	updateTorrentStatuses(_personalCurl);
	updateGUISignal = SIGNAL_UPDATEBARS;
	
	deleteCurl(_personalCurl);
	dataThreadRunning=0;
	if (_passedData==NULL){
		pthread_exit(NULL);
	}
	return NULL;
}

// Passed data is a malloc'd string of the url or magnent
void* threadedAddTorrent(void* _passedData){
	printf("Trying to add %s\n",(char*)_passedData);

	CURL* _personalCurl = newCurl();

	char* _foundToken = addTorrentLink(_personalCurl,(char*)_passedData,_userAccessToken);
	singleStatus* _placeholderStatus = increaseTorrentArray();
	_placeholderStatus->token = _foundToken;
	_placeholderStatus->healthBar = NEWTORRENT_HEALTHBAR;

	syncProgressBars();
	
	free(_passedData);
	deleteCurl(_personalCurl);
	pthread_exit(NULL);
	return NULL;
}

void waitForDataThreadEnd(){
	if (dataThread==0 || dataThreadRunning==0){
		return;
	}
	int _possibleError = pthread_join(dataThread, NULL);
	if(_possibleError){
		fprintf(stderr, "Error joining thread\n");
		printf("%d\n",_possibleError);
	}
}
//g_object_set_data
//void syncFileList(){
//	int i;
//	for (i=0;i<totalFileInfos;++i){
//		addFileViewerEntry(myFileInfos[i]);
//	}
//}
void syncFileList(){
	int i;
	if (totalGUIFileList>totalFileInfos){
		for (i=totalFileInfos;i<totalGUIFileList;++i){
			gtk_widget_destroy(guiFileListEntry[i]);
		}
		totalGUIFileList = totalFileInfos;
	}else if (totalGUIFileList<totalFileInfos){
		guiFileListEntry = realloc(guiFileListEntry,totalFileInfos*sizeof(GtkWidget*));
		for (i=totalGUIFileList;i<totalFileInfos;++i){
			guiFileListEntry[i] = gtk_list_box_row_new();
			gtk_container_add (GTK_CONTAINER (guiFileListEntry[i]), gtk_label_new ("temp"));
			gtk_list_box_insert (GTK_LIST_BOX (fileListBox), guiFileListEntry[i],-1);
			gtk_widget_show_all (guiFileListEntry[i]);
		}
		totalGUIFileList = totalFileInfos;
	}
	/*_folderColor.red=248/(double)255;
	_folderColor.blue=245/(double)255;
	_folderColor.green=225/(double)255;
	_folderColor.alpha=1.0;*/

	for (i=0;i<totalFileInfos;++i){
		gtk_list_box_row_set_activatable(GTK_LIST_BOX_ROW(guiFileListEntry[i]),myFileInfos[i].isFolder);
		g_object_set_data(G_OBJECT(guiFileListEntry[i]),ARRAYINDEXKEY,GINT_TO_POINTER(i));
		gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(guiFileListEntry[i]))),myFileInfos[i].filename);

		gtk_widget_override_color(gtk_bin_get_child(GTK_BIN(guiFileListEntry[i])),GTK_STATE_FLAG_NORMAL,myFileInfos[i].isFolder ? &_folderColor : NULL);
	}

	if (currentBrowserDir!=NULL){
		gtk_label_set_text(GTK_LABEL(folderViewerTopLabel),currentBrowserDir);
	}
}

// Take the info from torrentStatuses and pushes it to progressBars
void syncProgressBars(){
	int i;
	//
	if (totalProgressBars>totalStatuses){
		for (i=totalStatuses;i<totalProgressBars;++i){
			gtk_widget_destroy(progressBars[i]);
		}
		totalProgressBars = totalStatuses;
	}else if (totalProgressBars<totalStatuses){
		progressBars = realloc(progressBars,totalStatuses*sizeof(GtkWidget*));
		for (i=totalProgressBars;i<totalStatuses;++i){
			progressBars[i] = gtk_progress_bar_new();
			gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(progressBars[i]),1);
			//gtk_box_pack_start(GTK_BOX(progressBox),progressBars[i],1,1,0);
			gtk_container_add (GTK_CONTAINER(progressBox),progressBars[i]);
			gtk_widget_show(progressBars[i]);
		}
		totalProgressBars = totalStatuses;
	}
	//
	for (i=0;i<totalStatuses;++i){
		if (myStatuses[i].filename==NULL){
			gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressBars[i]),"Trying to add to downloads or queue");
		}else{
			char _completeLabel[strlen(myStatuses[i].filename)+strlen(myStatuses[i].timeLeft)+strlen("[] left")+1];
			sprintf(_completeLabel,"[%s left] %s",myStatuses[i].timeLeft,myStatuses[i].filename);
			gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressBars[i]),_completeLabel);
			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progressBars[i]),myStatuses[i].progress);
		}
	}
}

// Take the info from currentHDDL and pushes it to guiHDDLBars
void syncHDDLProgress(){
	// Remove finished files
	int i;
	int _oldTotalHDDL = totalHDDL;
	for (i=0;i<_oldTotalHDDL;++i){
		if ((*currentHDDL[i])._isDone){
			--totalHDDL;
			free(currentHDDL[i]);
			currentHDDL[i]=NULL;
		}
	}
	if (totalHDDL!=_oldTotalHDDL){
		downloadInstance** _newHDDLArray = malloc(sizeof(downloadInstance*)*totalHDDL);
		int _nextFreeIndex=0;
		int i;
		for (i=0;i<_oldTotalHDDL;++i){
			if (currentHDDL[i]!=NULL){
				_newHDDLArray[_nextFreeIndex] = currentHDDL[i];
				++_nextFreeIndex;
			}
		}
		free(currentHDDL);
		currentHDDL = _newHDDLArray;
	}

	if (numHDDLBars>totalHDDL){
		for (i=totalHDDL;i<numHDDLBars;++i){
			gtk_widget_destroy(guiHDDLBars[i]);
		}
		numHDDLBars = totalHDDL;
	}else if (numHDDLBars<totalHDDL){
		guiHDDLBars = realloc(guiHDDLBars,totalHDDL*sizeof(GtkWidget*));
		for (i=totalProgressBars;i<totalHDDL;++i){
			guiHDDLBars[i] = gtk_progress_bar_new();
			gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(guiHDDLBars[i]),1);
			gtk_container_add (GTK_CONTAINER(localDLListUIBox),guiHDDLBars[i]);
			gtk_widget_show(guiHDDLBars[i]);
		}
		numHDDLBars = totalHDDL;
	}
	for (i=0;i<totalHDDL;++i){
		char _completeLabel[strlen((*currentHDDL[i]).destFile)+strlen("[999999999 kbps] ")+1];
		sprintf(_completeLabel,"[%ld kbps] %s",(long)(*currentHDDL[i]).downloadSpeed,(*currentHDDL[i]).destFile);

		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(guiHDDLBars[i]),_completeLabel);
		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(guiHDDLBars[i]),((*currentHDDL[i]).lastDownloaded/(double)(*currentHDDL[i]).downloadGoal));
	}
}

gboolean updateData(gpointer user_data){
	if (!dataThreadRunning && updateDataSignal!=SIGNAL_DLNONE){
		if (updateDataSignal==SIGNAL_DLBARS){
			dataThreadRunning=1;
			if(pthread_create(&dataThread, NULL, threadedDownloadBars, NULL)) {
				printf("Error creating thread\n");
			}
		}else if (updateDataSignal==SIGNAL_DLFILELIST){
			dataThreadRunning=1;
			if(pthread_create(&dataThread, NULL, threadedDownloadFilelist, NULL)) {
				printf("Error creating thread\n");
			}
			if (isOneshotData){
				updateDataSignal = SIGNAL_DLNONE;
			}
		}else{
			printf("Bad update value for data, %d\n",updateDataSignal);
		}
	}
	return 1;
}

gboolean updateGUI(gpointer user_data){
	if (updateGUISignal!=SIGNAL_NONE){
		if (updateGUISignal==SIGNAL_UPDATEBARS){
			printf("Updating progress bars...\n");
			syncProgressBars();
			updateGUISignal = SIGNAL_NONE;
		}else if (updateGUISignal==SIGNAL_UPDATEFILELIST){
			printf("Updating file list GUI...\n");
			syncFileList();
			//if (isOneshotGUI)
			updateGUISignal = SIGNAL_NONE;
		}else if (updateGUISignal==SIGNAL_UDPATEHDDLPROGRESS){
			printf("Updating DDL GUI...\n");
			syncHDDLProgress();
		}else{
			printf("Bad update value for GUI, %d\n",updateGUISignal);
		}
	}
	return 1;
}

void clickSwitchFilemanager(GtkWidget* widget, gpointer data){
	switchToFileManager();
	g_print ("Hello World\n");
}
void clickQuitButton(GtkWidget* widget, gpointer data){
	gtk_widget_destroy(mainWindow);
}

void* threadedDelete(void* _passedPointer){
	struct deletionInfo _gottenInfo = *(struct deletionInfo*)_passedPointer;
	// Init
	CURL* _personalCurl = newCurl();
	
	// Work
	resetCurlSettings(_personalCurl);
	struct curl_slist* _apiRequestHeader = newCurlHeaders();
	prepareAPIHeader(_userAccessToken,&_apiRequestHeader);
	applyCurlHeaders(_personalCurl,_apiRequestHeader);
	curl_easy_setopt(_personalCurl, CURLOPT_CUSTOMREQUEST, "DELETE");

	char _completeUrl[strlen(WEBSITEPREFIX)+strlen("/v2/files/")+strlen(myFileInfos[_gottenInfo.passedIndex].filecode)+1];
	strcpy(_completeUrl,WEBSITEPREFIX);
	if (myFileInfos[_gottenInfo.passedIndex].isFolder==0){
		strcat(_completeUrl,"/v2/files/");
	}else{
		strcat(_completeUrl,"/v2/cloud/");
	}
	strcat(_completeUrl,myFileInfos[_gottenInfo.passedIndex].filecode);

	memoryStruct _myDownloadedData;
	_myDownloadedData.memory=NULL;
	downloadWebpageData(_personalCurl, &_myDownloadedData, _completeUrl);
	free(_myDownloadedData.memory);

	//deletionInfo

	//updateTorrentStatuses(_personalCurl);
	//updateGUISignal = SIGNAL_UPDATEBARS;
	//deleteCurl(_personalCurl);

	// End
	--*(int*)_gottenInfo.totalDeletions;
	if (*(int*)_gottenInfo.totalDeletions==0){
		printf("done.\n");
		updateDataSignal = SIGNAL_DLFILELIST;
		dataThreadRunning=0;
		free(_gottenInfo.totalDeletions);
	}
	free(_passedPointer);
	pthread_exit(NULL);
	return NULL;
}

void _deleteForeach(GtkListBox* box, GtkListBoxRow* row, gpointer user_data){
	int _gottenIndex = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(row),ARRAYINDEXKEY));
	dataThreadRunning=1;

	struct deletionInfo* _infoToPass = malloc(sizeof(struct deletionInfo));
	_infoToPass->passedIndex = _gottenIndex;
	_infoToPass->totalDeletions = user_data;

	pthread_t _tempHoldThread;
	if(pthread_create(&_tempHoldThread, NULL, threadedDelete, _infoToPass)) {
		printf("Error creating thread\n");
	}

	//threadedDelete

	//waitForDataThreadEnd();
	//clearFileList();
	//changeMallocString(&currentFolderBrowseCode,myFileInfos[_gottenIndex].filecode);
	//updateDataSignal = SIGNAL_DLFILELIST;
	//updateData(NULL);
	//updateDataSignal = SIGNAL_DLNONE;
	//
	//threadedDelete();
}
void _countForeach(GtkListBox* box, GtkListBoxRow* row, gpointer user_data){
	++*(int*)user_data;
}

void fileManagerDeleteButton(GtkWidget* widget, gpointer data){
	// Step 1 - Count how many we've counted
	int _countedSelection=0;
	gtk_list_box_selected_foreach(GTK_LIST_BOX(fileListBox),_countForeach,&_countedSelection);

	if (_countedSelection==0){
		return;
	}

	// Prompt deletion
	GtkWidget* _confirmDialog = gtk_message_dialog_new (GTK_WINDOW(mainWindow), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "Really delete %d files?", _countedSelection);
	char _isOk = (gtk_dialog_run(GTK_DIALOG (_confirmDialog))==GTK_RESPONSE_YES);
	gtk_widget_destroy (_confirmDialog);
	if (_isOk){
		int* _filesToDelet = malloc(sizeof(int));
		*_filesToDelet = _countedSelection;
		gtk_list_box_selected_foreach(GTK_LIST_BOX(fileListBox),_deleteForeach,_filesToDelet);

		// Put this last otherwise it clears our selection
		clearFileList();
	}
}

void _downloadForeach(GtkListBox* box, GtkListBoxRow* row, gpointer user_data){
	int* _infoIndex = user_data;

	int _myIndex = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(row),ARRAYINDEXKEY));
	if (myFileInfos[_myIndex].filename==NULL || strcmp(myFileInfos[_myIndex].filename,"..")==0){
		// Exclude parent folder entry
		return;
	}

	currentHDDL[*_infoIndex] = malloc(sizeof(downloadInstance*));
	downloadInstance* _myInstance = malloc(sizeof(downloadInstance));
	(currentHDDL[*_infoIndex])=_myInstance;


	char* _downloadThis = getHDDL(_generalUseCurl,myFileInfos[_myIndex].filecode,_userAccessToken,myFileInfos[_myIndex].isFolder);
	char _completeOutPath[strlen(downloadsDir)+strlen(myFileInfos[_myIndex].filename)+1];
	sprintf(_completeOutPath,"%s%s",downloadsDir,myFileInfos[_myIndex].filename);

	_myInstance->_isDone=0;
	_myInstance->destFile = strdup(_completeOutPath);
	_myInstance->url = _downloadThis;

	downloadFileSync(_myInstance);
	// 
	++*_infoIndex;
}

void fileManagerDownloadButton(GtkWidget* widget, gpointer data){
	int _countedSelection=0;
	gtk_list_box_selected_foreach(GTK_LIST_BOX(fileListBox),_countForeach,&_countedSelection);

	// The file manager is one shot GUI and data, the thread shouldn't be running
	currentHDDL = realloc(currentHDDL,sizeof(downloadInstance*)*(totalHDDL+_countedSelection));
	int _nextHDDLIndex = totalHDDL;
	gtk_list_box_selected_foreach(GTK_LIST_BOX(fileListBox),_downloadForeach,&_nextHDDLIndex);
	currentHDDL = realloc(currentHDDL,sizeof(downloadInstance*)*_nextHDDLIndex); // If slots went unused.
	totalHDDL = _nextHDDLIndex;

	/*fileInfo _currentInfo = myFileInfos[GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtk_list_box_get_selected_row( GTK_LIST_BOX(fileListBox) )),ARRAYINDEXKEY))];
	char* _downloadThis = getHDDL(_generalUseCurl,_currentInfo.filecode,_userAccessToken,0);

	char _completeOutPath[strlen("./")+strlen(_currentInfo.filename)+1];
	sprintf(_completeOutPath,"./%s",_currentInfo.filename);*/

/*
	// The file manager is one shot GUI and data, the thread shouldn't be running
	++totalHDDL;
	currentHDDL = realloc(currentHDDL,sizeof(downloadInstance)*totalHDDL);
	currentHDDL[totalHDDL-1]._isDone=0;
	currentHDDL[totalHDDL-1].destFile = strdup(_completeOutPath);
	currentHDDL[totalHDDL-1].url = _downloadThis;
	downloadFileSync(&currentHDDL[totalHDDL-1]);
*/
}

void fileManagerBackButton(GtkWidget* widget, gpointer data){
	switchToStatusScreen();
}

void taskbarActivate(GtkWidget* widget, gpointer data){
	gtk_widget_show(mainWindow);
	//printf("bla.\n");
}

/*
void _listCoutnerForeachHelper(GtkListBox* box, GtkListBoxRow* row, gpointer user_data){
	printf("what?\n");
	++*((int*)user_data);
}
int getListBoxRows(GtkWidget* _passedListbox){
	int _foundTotalRows=0;
	gtk_list_box_selected_foreach(GTK_LIST_BOX(_passedListbox),_listCoutnerForeachHelper,&_foundTotalRows);
	return _foundTotalRows;
}
*/
void fileFolderActivated (GtkListBox* box, GtkListBoxRow* row, gpointer user_data){
	//g_object_get_data
	//g_object_set_data
	int _gottenIndex = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(row),ARRAYINDEXKEY));

	waitForDataThreadEnd();

	clearFileList();
	changeMallocString(&currentFolderBrowseCode,myFileInfos[_gottenIndex].filecode);
	updateDataSignal = SIGNAL_DLFILELIST;
	updateData(NULL);
	updateDataSignal = SIGNAL_DLNONE;

	printf("activated!!!\n");
}

void torrentTextboxSubmit (GtkWidget* widget, gpointer data){
	char* _dataPass = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
	pthread_t _tempHoldThread;
	if(pthread_create(&_tempHoldThread, NULL, threadedAddTorrent, _dataPass)) {
		printf("Error creating thread\n");
	}
	gtk_entry_set_text(GTK_ENTRY(widget),"");
}

void userTextboxSubmitCode (GtkWidget* widget, gpointer data){
	const char* _userCodeGiven = gtk_entry_get_text(GTK_ENTRY(widget));
	_userAccessToken = getAccessToken(_generalUseCurl,_userCodeGiven);
	
	if (_userAccessToken!=NULL){
		saveCacheAccess(_userAccessToken);

		gtk_widget_destroy(tempStuffBox);
		supportStartMainGUI();
	}else{
		printf("Error getting user access token.\n");
	}

	gtk_entry_set_text(GTK_ENTRY(widget),"");
}

void hideAllScreens(){
	gtk_widget_hide(fileManagerUIBox);
	gtk_widget_hide(statusUIBox);
	gtk_widget_hide(localDLListUIBox);
}

void switchInit(){
	updateGUISignal = SIGNAL_NONE;
	updateDataSignal = SIGNAL_DLNONE;
	waitForDataThreadEnd();
	updateGUISignal = SIGNAL_NONE;
	updateDataSignal = SIGNAL_DLNONE;

	isOneshotData=0;
	isOneshotGUI=0;
	hideAllScreens();
}

void switchToStatusScreen(){
	switchInit();
	updateDataSignal = SIGNAL_DLBARS;

	gtk_widget_show(statusUIBox);
}

void switchToFileManager(){
	switchInit();
	clearFileList();
	updateDataSignal = SIGNAL_DLFILELIST;
	isOneshotData=1;
	isOneshotGUI=1;
	updateData(NULL);
	//updateGUI(NULL);

	gtk_widget_show(fileManagerUIBox);
}

void switchToLocalDLProgress(){
	switchInit();
	updateGUISignal = SIGNAL_UDPATEHDDLPROGRESS;
	updateGUI(NULL);
	gtk_widget_show(localDLListUIBox);
}

void supportStartCodeInput(){
	tempStuffBox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	gtk_container_add (GTK_CONTAINER (mainWindow), tempStuffBox);

	GtkWidget* _promptText = gtk_label_new("To get started, use your web browser to go to https://bitport.io, sign in, go to https://bitport.io/get-access, enter the access code, and press enter.");
	gtk_label_set_line_wrap(GTK_LABEL(_promptText),1);
	gtk_box_pack_start(GTK_BOX(tempStuffBox),_promptText,0,0,0);

	GtkWidget* _userTextbox = gtk_entry_new();
	gtk_entry_set_placeholder_text(GTK_ENTRY(_userTextbox),"Access code");
	gtk_box_pack_end(GTK_BOX(tempStuffBox),_userTextbox,0,0,0);
	g_signal_connect (_userTextbox, "activate", G_CALLBACK (userTextboxSubmitCode), NULL);

	gtk_widget_show_all(tempStuffBox);
}

void supportStartMainGUI(){

	/////////////////////////////////////////////////////////////////////
	mainBox=NULL; // Contains all screen's boxes
	statusUIBox = NULL; // Box with status UI elements
	fileManagerUIBox=NULL; // Box with file manager UI elements

	GtkWidget* testButton; // Temp variable to hold new buttons
	/////////////////////////////////////////////////////////////////////
	GtkWidget* _statusButtonGrid=NULL; // Box with our buttons
	GtkWidget* _userTextbox=NULL;
	progressBox=NULL; // Box for our progress bar
	/////////////////////////////////////////////////////////////////////
	GtkWidget* fileListScrollHolder=NULL;
	GtkWidget* _fileManagerButtonGrid=NULL;
	fileListBox=NULL;
	/////////////////////////////////////////////////////////////////////

	totalProgressBars=0;
	totalStatuses=0;
	progressBars = NULL;
	myStatuses=NULL;

	// Main box holds all other screen's boxes
	mainBox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	gtk_container_add (GTK_CONTAINER (mainWindow), mainBox); // Add main box to the window

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// Make the main box for holding everything
	statusUIBox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	gtk_box_pack_start(GTK_BOX(mainBox),statusUIBox,1,1,0); // Important that this 4th argument is 0

	// Make box for progress bars
	progressBox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	gtk_box_pack_start(GTK_BOX(statusUIBox),progressBox,1,1,0); // Important that this 4th argument is 0

	// Make the button grid
	_statusButtonGrid = gtk_grid_new ();
	gtk_grid_set_column_homogeneous(GTK_GRID(_statusButtonGrid),FALSE); // Prevent stupid alignment
	gtk_grid_set_row_homogeneous(GTK_GRID(_statusButtonGrid),FALSE);
	gtk_box_pack_end(GTK_BOX(statusUIBox),_statusButtonGrid,0,0,0);
	//gtk_container_add (GTK_CONTAINER (statusUIBox), _statusButtonGrid); // Add button grid to the main box

	// A test button
	testButton = gtk_button_new_with_label ("My Files");
	g_signal_connect (testButton, "clicked", G_CALLBACK (clickSwitchFilemanager), NULL);
	gtk_grid_attach (GTK_GRID (_statusButtonGrid), testButton, 0, 0, 1, 1);

	// A second test button
	testButton = gtk_button_new_with_label ("Quit");
	g_signal_connect (testButton, "clicked", G_CALLBACK (clickQuitButton), NULL);
	gtk_grid_attach (GTK_GRID (_statusButtonGrid), testButton, 1, 0, 1, 1);

	_userTextbox = gtk_entry_new();
	gtk_entry_set_placeholder_text(GTK_ENTRY(_userTextbox),"Torrent or magnet link");
	gtk_grid_attach (GTK_GRID (_statusButtonGrid), _userTextbox, 0, 1, 2, 1);
	g_signal_connect (_userTextbox, "activate", G_CALLBACK (torrentTextboxSubmit), NULL);

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// Start our other UI
	fileManagerUIBox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	gtk_box_set_homogeneous(GTK_BOX(fileManagerUIBox),0);
	gtk_box_pack_start(GTK_BOX(mainBox),fileManagerUIBox,1,1,0); 
	
	folderViewerTopLabel = gtk_label_new("Please wait...");
	gtk_box_pack_start(GTK_BOX(fileManagerUIBox),folderViewerTopLabel,0,0,0);


	// Scroll box
	fileListScrollHolder = gtk_scrolled_window_new(NULL,NULL);
	// File lis box
	fileListBox = gtk_list_box_new();
	gtk_list_box_set_selection_mode(GTK_LIST_BOX(fileListBox),GTK_SELECTION_MULTIPLE);
	gtk_list_box_set_activate_on_single_click(GTK_LIST_BOX(fileListBox), 0);
	
	g_signal_connect (fileListBox, "row-activated", G_CALLBACK (fileFolderActivated), NULL);

	// Put them together
	gtk_container_add (GTK_CONTAINER(fileListScrollHolder),fileListBox);
	// Add to our file manager UI box
	gtk_box_pack_start(GTK_BOX(fileManagerUIBox),fileListScrollHolder,1,1,0);

	_fileManagerButtonGrid = gtk_grid_new();
	gtk_box_pack_start(GTK_BOX(fileManagerUIBox),_fileManagerButtonGrid,0,0,0);

	testButton = gtk_button_new_with_label("Back");
	g_signal_connect (testButton, "clicked", G_CALLBACK (fileManagerBackButton), NULL);
	gtk_grid_attach (GTK_GRID (_fileManagerButtonGrid), testButton, 0, 0, 1, 1);

	testButton = gtk_button_new_with_label("Delete");
	g_signal_connect (testButton, "clicked", G_CALLBACK (fileManagerDeleteButton), NULL);
	gtk_grid_attach (GTK_GRID (_fileManagerButtonGrid), testButton, 1, 0, 1, 1);

	testButton = gtk_button_new_with_label("Download");
	g_signal_connect (testButton, "clicked", G_CALLBACK (fileManagerDownloadButton), NULL);
	gtk_grid_attach (GTK_GRID (_fileManagerButtonGrid), testButton, 2, 0, 1, 1);

	testButton = gtk_button_new_with_label("Download Progress");
	g_signal_connect (testButton, "clicked", G_CALLBACK (switchToLocalDLProgress), NULL);
	gtk_grid_attach (GTK_GRID (_fileManagerButtonGrid), testButton, 3, 0, 1, 1);

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	localDLListUIBox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	gtk_box_set_homogeneous(GTK_BOX(localDLListUIBox),0);
	gtk_box_pack_start(GTK_BOX(mainBox),localDLListUIBox,1,1,0);

	testButton = gtk_button_new_with_label("My Files");
	g_signal_connect (testButton, "clicked", G_CALLBACK (switchToFileManager), NULL);
	gtk_box_pack_start(GTK_BOX(localDLListUIBox),testButton,0,0,0);

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	gtk_widget_show_all(mainBox);

	gtk_widget_hide(fileManagerUIBox);
	gtk_widget_hide(statusUIBox);
	gtk_widget_hide(fileManagerUIBox);
	//gtk_widget_show_all(fileManagerUIBox);
	switchToStatusScreen();
	//switchToFileManager();

	// Add the progress bar update function
	updateGUISignal = SIGNAL_NONE;
	guiRefreshFunctionID = g_timeout_add_seconds(UPDATE_SECONDS_GUI,updateGUI,NULL);
	updateDataSignal = SIGNAL_DLBARS;
	dataRefreshFunctionID = g_timeout_add_seconds(UPDATE_SECONDS_DATA,updateData,NULL);

	// Start off with some bars
	//updateTorrentStatuses();
	//	updateGUISignal = SIGNAL_UPDATEBARS;
	//updateGUI(NULL);
}

void realStartTestgui(GtkApplication* _passedApp, gpointer user_data){
	// Make the main window
	mainWindow = gtk_application_window_new (_passedApp);
	gtk_window_set_title (GTK_WINDOW (mainWindow), "Bitport Test");
	gtk_container_set_border_width (GTK_CONTAINER (mainWindow), 4); // 4 pixles of padding from the edge of the window
	g_signal_connect(G_OBJECT(mainWindow), "delete-event", G_CALLBACK(gtkHideInsteadOfClose), NULL);
	gtk_widget_set_size_request(GTK_WIDGET(mainWindow),300,300);

	if (_userAccessToken==NULL){
		supportStartCodeInput();
	}else{
		supportStartMainGUI();
	}

	#if ENABLETASKBAR
		//https://developer.gnome.org/gtk3/stable/GtkStatusIcon.html
		GtkStatusIcon* myTaskbarIcon = gtk_status_icon_new_from_file ("./icon.png");
		g_signal_connect (myTaskbarIcon, "activate", G_CALLBACK (taskbarActivate), NULL);
	#endif

	gtk_widget_show(mainWindow);
}


void startgui(){
	_folderColor.red=.5;
	_folderColor.blue=1.0;
	_folderColor.green=0;
	_folderColor.alpha=1.0;

	GtkApplication* myGTIKApp=NULL;

	int status;
	myGTIKApp = gtk_application_new ("org.notabug.moron.waifu.nathan.bp", G_APPLICATION_FLAGS_NONE);
	g_signal_connect (myGTIKApp, "activate", G_CALLBACK (realStartTestgui), NULL);
	status = g_application_run (G_APPLICATION (myGTIKApp), 0, NULL);
	g_object_unref (myGTIKApp);

	// Prevent warning
	if (status){
		return;
	}
}